/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package downloadtwitterrelations;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import twitter4j.*;
import twitter4j.auth.AccessToken;
import java.text.SimpleDateFormat;

/**
 *
 * @author Ranjan
 */
public class TwitterRelations {
    private static Twitter twitter;
    private final static Logger logger = Logger.getLogger(TwitterRelations.class.getName());
    
    //Using mssql connector 
	private static Connection connect = null;
	private static Statement statement = null;	
	private static ResultSet resultSet = null;		

	public void startDownload(String username) throws Exception {
        long sleepTime = 60000; //1 min to start with

        try {
            twitter = new TwitterFactory().getInstance();
            getFollowers(username);
            //getFollowersTest(username);
        } catch (TwitterException ex) {
            Logger.getLogger(TwitterRelations.class.getName()).log(Level.SEVERE, null, ex);
            if (ex.exceededRateLimitation()) {
                           System.out.println("blocked!");
                           sleepTime*=2; //double the sleeptime
                       }
        }
       /* sleeping code */
       try {
               System.out.println("Sleeping for (minutes):" +(sleepTime/1000)/60);
               Thread.sleep(sleepTime);
               if (sleepTime / 1.5 > 60000) //dont fall below a minute
                   sleepTime/= 1.5; //lower the sleep time a little
       } catch (InterruptedException e) {
               e.printStackTrace();
       }
    }
    
	private static void openConnection() {
		String consumerKey = "ulykiAisbBZmm3yO3Gljg";
		String consumerSecret = "oYevMEV6utATGS6ZXnk5oamlTgYQJ8W5d3TtKsIi4";
		String twitterToken = "535536803-slZu3SIYP5eZkpSPCt6orFaRfSUAxAu5l3VgQP95";
		String twitterTokenSecret = "S3FQxrLeggW7VjL71g2fj08K1RFkCDdEDVlcfStTNc";
		
		twitter.setOAuthConsumer(consumerKey, consumerSecret);
		AccessToken accessToken = new AccessToken(twitterToken, twitterTokenSecret);
	
		//Setup our connection
		twitter.setOAuthAccessToken(accessToken);
		//Now grab our twitter name to ensure we are working
		try {
			System.out.format ("Hello %s", twitter.getScreenName());
			logger.info("Connection successful!");
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TwitterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static void closeConnection() {
		System.out.println("Closing connection");
		logger.info("Closing Connection");
		//Shutdown the connection
		twitter.shutdown();        	
	}
	
	
	private static void openMSSqlConnection() throws Exception {
		
		//String url = "jdbc:mysql://127.0.0.1:3306/tversecrawler";
		String url = "jdbc:sqlserver://127.0.0.1:1433;database=tversecrawler;integratedSecurity=true;";
		String username = "tversecrawler";
		String password = "Firehawk03";
				
		try {
			    System.out.println("Connecting database...");
			    connect = DriverManager.getConnection(url, username, password);
			    System.out.println("Database connected!");
			} catch (SQLException e) {
			    throw new RuntimeException("Cannot connect the database!", e);
		} 
			
	}
	
	private static void closeMSSqlConnection() {
        //Close the MSsql driver for our database
		try {
				if (resultSet != null) {
					resultSet.close();
				}
				if (statement != null) {
					statement.close();
				}
				if (connect != null) {
					connect.close();
				}
		} catch (Exception e) {	}
	}

	@SuppressWarnings("deprecation")
	public void getFollowersTest(String screenname) throws Exception {
		openConnection();
		
		User user = twitter.showUser(screenname);
		System.out.println("Userid for the screenname "+screenname+" is : " + user.getId());
		
        long lCursorIDs = -1;  //Twitter allows to start with -1
                
        IDs followerIds_class = twitter.getFollowersIDs(screenname, lCursorIDs);
        long[] followerids = followerIds_class.getIDs();
        System.out.println("Number of followers: "+followerids.length);  
		
        while(true) {
        	
        PagableResponseList<User> statuses = twitter.getFollowersStatuses(screenname, lCursorIDs);// Run this for Followers 
        ListIterator<User> li = statuses.listIterator(); 
		
          	
            while (li.hasNext())
    		{
            	User ur = li.next();
        		System.out.println("User Id: "+ur.getId());
	        	System.out.println("Name: "+ur.getName());
    		}
        	lCursorIDs = statuses.getNextCursor();
        	//statuses = twitter.getFollowersStatuses(screenname, lCursorIDs);
        	
		    //cursor = followerIds_class.getNextCursor();
		    if (lCursorIDs < 1L) {
		        break;
		    }
    	}
        
		
/*		long lCursorIDs = -1;
		
        IDs followerIds_class = twitter.getFollowersIDs(screenname, lCursorIDs);
        long[] followerids = followerIds_class.getIDs();
        System.out.println("Number of followers: "+followerids.length);  
        
		ResponseList<User>  statuses =  twitter.lookupUsers(followerids);
		// System.out.println(statuses);    
		ListIterator<User> li = statuses.listIterator();
		String[] fInfoArray = new String[statuses.size()]; 
        int i = 0;
        while (li.hasNext())
		{
			fInfoArray[i] = li.next().getName();
			System.out.println ("Info " + i + ": " + fInfoArray[i]);
			i++;
		}
*/
		
/*		long cursor = -1L;
		while (true) {
		    
			//IDs follorwes = twitter.getFollowersIDs("screen_name", cursor);
		    //long[] ids = followers.getIDs();
		    
		    IDs followerIds_class = twitter.getFollowersIDs(screenname, cursor);
		    long[] followerids = followerIds_class.getIDs();
		    
		    for (int i = 0, len = followerids.length; i < len; i += 100) {
		        int endIndex = Math.min(i + 100, len);
		        // for Java6
		        // long[] targets = Arrays.copyOfRange(ids, i, endIndex);
		        long[] targets = new long[endIndex - i];
		        System.arraycopy(followerids, i, targets, 0, targets.length);
		        List<User> userList = twitter.lookupUsers(targets);
		        for (int j = 0, jLen = userList.size(); j < jLen; ++j) {
		            User u = userList.get(i);
		            // must not use getProfileImage(), it's for developping only.
		            // https://dev.twitter.com/docs/api/1/get/users/profile_image/%3Ascreen_name
		            //image = twitter.getProfileImage(u, imageSize);
		            
		            //URL imageUrl = u.getProfileImageUrl();
		            // Your code here is.
	        		System.out.println("User Id: "+u.getId());
		        	System.out.println("Name: "+u.getName());
		        }
		    }
		    cursor = followerIds_class.getNextCursor();
		    if (cursor < 1L) {
		        break;
		    }
		} 
		
		*/
		closeConnection();
	}
	
    /**
     * Gets the followers of screen name
     * @throws Exception 
     */
    public void getFollowers(String screenname) throws Exception {
    	//Setup our Connection
    	openConnection();
    	
    	int totalUser=0;
    	
    	User user = twitter.showUser(screenname);
		System.out.println("Userid for the screenname "+screenname+" is : " + user.getId());
		
        long lCursorIDs = -1;  //Twitter allows to start with -1
                
        IDs followerIds_class = twitter.getFollowersIDs(screenname, lCursorIDs);
        long[] followerids = followerIds_class.getIDs();
        System.out.println("Number of followers: "+followerids.length);         
        
        openMSSqlConnection();
        
        while(true) {

//First Method:  limits to 350 calls per hour 
        		// User ur = twitter.showUser(i);
        		 
//Second Method:  
       /* 		ResponseList<User>  statuses =  twitter.lookupUsers(followerids);
        		// System.out.println(statuses);    
        		ListIterator<User> li = statuses.listIterator();
        		String[] fInfoArray = new String[statuses.size()]; 
                int i = 0;
                while (li.hasNext())
				{
					fInfoArray[i] = li.next().getName();
					System.out.println ("Info " + i + ": " + fInfoArray[i]);
					i++;
				}
		*/
//Third Method: 
            @SuppressWarnings("deprecation")
			PagableResponseList<User> statuses = twitter.getFollowersStatuses(screenname, lCursorIDs);// Run this for Followers
            //PagableResponseList<User> statuses = twitter.getFriendsStatuses(screenname, -1);//Run this for Followings
            ListIterator<User> li = statuses.listIterator();

		    while (li.hasNext()) {
		        User ur = li.next();
		        	
		        		System.out.println("User Id: "+ur.getId());
			        	System.out.println("Name: "+ur.getName());
			   /*     	System.out.println("ScreenName: "+ur.getScreenName());
			        	System.out.println("Location: "+ur.getLocation());
			        	System.out.println("FollowersCount: "+ur.getFollowersCount());
			        	System.out.println("FriendsCount: "+ur.getFriendsCount());
			        	System.out.println("Description: "+ur.getDescription());
			        	System.out.println("CreatedAt: "+ur.getCreatedAt());
			        	System.out.println("TimeZone: "+ur.getTimeZone());
			        	System.out.println("Language: "+ur.getLang());
			        	System.out.println("AccessLevel: "+ur.getAccessLevel());
			        	System.out.println("UtcOffset: "+ur.getUtcOffset());
			        	System.out.println("URL: "+ur.getURL());
			        	System.out.println("FavouritesCount: "+ur.getFavouritesCount());
			        	System.out.println("ListedCount: "+ur.getListedCount());
			        	System.out.println("ProfileBackgroundColor: "+ur.getProfileBackgroundColor());
			        	System.out.println("ProfileBackgroundImageUrl: "+ur.getProfileBackgroundImageUrl());
			        	System.out.println("ProfileBackgroundImageUrlHttps: "+ur.getProfileBackgroundImageUrlHttps());
			        	System.out.println("ProfileLinkColor: "+ur.getProfileLinkColor());
			        	System.out.println("ProfileSidebarBorderColor: "+ur.getProfileSidebarBorderColor());
			        	System.out.println("ProfileSidebarFillColor: "+ur.getProfileSidebarFillColor());
			        	System.out.println("ProfileTextColor: "+ur.getProfileTextColor());
			        	System.out.println("StatusesCount: "+ur.getStatusesCount());
			        	System.out.println("ProfileImageURL: "+ur.getProfileImageURL());
			        	System.out.println("ProfileImageUrlHttps: "+ur.getProfileImageUrlHttps());
			        	System.out.println("RateLimitStatus: "+ur.getRateLimitStatus());   */
			        		
			           //First check to see if we have already indexed this tweet	  
			           PreparedStatement stmtCheck = (PreparedStatement) connect.prepareStatement("select * from twt_user_information where user_id = '" + ur.getId() + "';");
			           resultSet = stmtCheck.executeQuery();
			          
			           if (!resultSet.next()) {	           	                       
			            System.out.println("NEW USER");
			            totalUser++;
			 	        
			            //Build our timestamp for insert
			          	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			          	
			            //Insert our data into the database
			            String stmt = "insert into twt_user_information (user_id, user_name, screen_name, location, followers_count, following_count, description, created_date, timezone, language, access_level, utcoffset, url, favourites_count, listed_count, profile_backcolor, profile_backimageurl, profile_backimageurlhttps, profile_linkcolor, profile_sidebar_borderclr, profile_sidebar_fillclr, profile_textclr, status_count, profile_imageurl, profile_imageurlhttps, follflag, ratelimit_status, seed_id)" +
			            			" values (" + 
			            			"'"+ur.getId()+"',"+
			            			"'"+(ur.getName()).replace("'", ".")+"',"+   
			                        "'"+ur.getScreenName()+"',"+
			                        "'"+ur.getLocation()+"',"+
			                        //"'"+(ur.getLocation()).replace("'", ".")+"',"+   //Run this for the second time else it will end up with null pointer exception
			                        "'"+ur.getFollowersCount()+"',"+
			                        "'"+ur.getFriendsCount()+"',"+
			                        "'"+ur.getDescription()+"',"+ 
			                        //"'"+(ur.getDescription()).replace("'", ".")+"',"+  //Run this for the second time else it will end up with null pointer exception
			                        "'"+(df.format(ur.getCreatedAt()))+"',"+	                       
			                        "'"+ur.getTimeZone()+"',"+
			                        "'"+ur.getLang()+"',"+    
			                        "'"+ur.getAccessLevel()+"',"+ 
			                        "'"+ur.getUtcOffset()+"',"+  
			                        "'"+ur.getURL()+"',"+
			                        "'"+ur.getFavouritesCount()+"',"+
			                        "'"+ur.getListedCount()+"',"+
			                        "'"+ur.getProfileBackgroundColor()+"',"+
			                        "'"+ur.getProfileBackgroundImageUrl()+"',"+
			                        "'"+ur.getProfileBackgroundImageUrlHttps()+"',"+
			                        "'"+ur.getProfileLinkColor()+"',"+
			                        "'"+ur.getProfileSidebarBorderColor()+"',"+
			                        "'"+ur.getProfileSidebarFillColor()+"',"+
			                        "'"+ur.getProfileTextColor()+"',"+
			                        "'"+ur.getStatusesCount()+"',"+
			                        "'"+ur.getProfileImageURL()+"',"+
			                        "'"+ur.getProfileImageUrlHttps()+"',"+
			                        " 1 ,"+	  // 1 - followers , 2 - following
			                        "'"+ur.getRateLimitStatus()+"',"+
			                        "'"+user.getId()+"')";
			                        
			            System.out.println("SQL: " + stmt);	
			            try	{
			                 	statement = connect.createStatement();
			                 	statement.execute(stmt);
			            	} catch (SQLException ex) {
			                 	System.out.println(ex); }  
			          } 
		          } 
		    lCursorIDs = statuses.getNextCursor();   
	        if (lCursorIDs < 1L) {
		        break;
		    }
    	}  
        closeMSSqlConnection();
        logger.info("done! ");
		System.out.println("This run got total " + totalUser + " Users ");
		closeConnection();
    }
}
